# -*- encoding: utf-8 -*-
"""
@File        : Rpc_server.py
@License     : (C)Copyright 2021 LeeRoc (cn) Lipeng
@Modify Time : 2021/7/30 6:42 下午
@Author      : LeeRoc
@Version     : 1.0
@Description : RPC服务
"""

import sys

sys.path.append('../')

from xmlrpc.server import SimpleXMLRPCServer
from xmlrpc.server import SimpleXMLRPCRequestHandler

from tool.current_time import current_time
from core.os_status_unit import *
from core.disrtibution_collection_unit import LinuxFile


def bytes2human(n):
    """
    内存单位转换
    :param n:
    :return:
    """
    symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
    prefix = {}
    for i, s in enumerate(symbols):
        prefix[s] = 1 << (i + 1) * 10
    for s in reversed(symbols):
        if n >= prefix[s]:
            value = float(n) / prefix[s]
            return '%.1f%s' % (value, s)
    return '%sB' % n


# Restrict to a particular path.
class RequestHandler(SimpleXMLRPCRequestHandler):
    rpc_paths = ('/RPC2',)


# xmlrpclib.Fault: :cannot marshal None unless allow_none is enabled”
# 这句话翻译过来的意思大概是“不能配置None出发allow_none为可用的”
# 解决办法：
# server = SimpleXMLRPCServer.SimpleXMLRPCServer((srv_conf[‘host’], srv_conf[‘port’]), allow_none=True)
# 修改服务端启动rpc服务时，设置allow_none为True。
with SimpleXMLRPCServer(('0.0.0.0', 8000),
                        requestHandler=RequestHandler, allow_none=True) as server:
    server.register_introspection_functions()

    # cpu信息
    @server.register_function(name='cpu_status')
    def get_cpu_info():
        cpu_percent = psutil.cpu_percent(interval=1)
        return str(cpu_percent) + '%'

    # 内存信息
    @server.register_function(name='internalmemory_status')
    def get_memory_info():
        virtual_memory = psutil.virtual_memory()
        free_memory = bytes2human(virtual_memory.free)

        return free_memory


    @server.register_function(name='distribute')
    def distribution(host: list, localhost_file: str, cluster_file: str):
        """
        用于分发文件到每个cluster中
        master to cluster
        队列分发
        :param host: 集群列表
        :param localhost_file: 集群的master文件目录下的文件
        :param cluster_file: remote端的one of cluster的文件目录下的文件
        """

        print("[%s] -- distributed file: %s from host: %s\n" % (current_time().get_current_time(),
                                                                localhost_file,
                                                                host[0]))

        dis = LinuxFile(host[0], host[1], host[2], host[3])
        dis.down_file(localhost_file, cluster_file)
        dis.close()


    @server.register_function(name='collect')
    def collection(host: list, cluster_file: str, localhost_file: str):
        """
        用于收集文件到当前主机下
        cluster to master
        队列收集
        :param host:  集群列表
        :param cluster_file: remote端的one of cluster的文件目录下的文件
        :param localhost_file: 集群的master文件目录下的文件
        """

        print("[%s] -- collect file: %s to host: %s\n" % (current_time().get_current_time(),
                                                          localhost_file,
                                                          host[0]))

        col = LinuxFile(host[0], host[1], host[2], host[3])
        col.up_file(cluster_file, localhost_file)
        col.close()


    # Run the server's main loop
    server.serve_forever()
